package com.ruoyi.purchase.controller;

import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.purchase.domain.ProcOrderExecution;
import com.ruoyi.purchase.domain.ProcOrder;
import com.ruoyi.purchase.service.IProcOrderExecutionService;
import com.ruoyi.purchase.service.IProcOrderService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.fin.domain.FinAccount;
import com.ruoyi.fin.service.IFinAccountService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.commons.lang3.StringUtils;

/**
 * 采购订单执行记录Controller
 * 
 * @author ruoyi
 * @date 2025-06-17
 */
@Controller
@RequestMapping("/purchase/execution")
public class ProcOrderExecutionController extends BaseController
{
    private String prefix = "purchase/execution";

    @Autowired
    private IProcOrderExecutionService procOrderExecutionService;
    
    @Autowired
    private IProcOrderService procOrderService;
    
    @Autowired
    private IFinAccountService finAccountService;

    private static final Logger logger = LoggerFactory.getLogger(ProcOrderExecutionController.class);

    @RequiresPermissions("purchase:execution:view")
    @GetMapping()
    public String execution()
    {
        return prefix + "/execution";
    }

    /**
     * 查询采购订单执行记录列表
     */
    @RequiresPermissions("purchase:execution:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(ProcOrderExecution procOrderExecution)
    {
        startPage();
        List<ProcOrderExecution> list = procOrderExecutionService.selectProcOrderExecutionList(procOrderExecution);
        return getDataTable(list);
    }

    /**
     * 导出采购订单执行记录列表
     */
    @RequiresPermissions("purchase:execution:export")
    @Log(title = "采购订单执行记录", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(ProcOrderExecution procOrderExecution)
    {
        List<ProcOrderExecution> list = procOrderExecutionService.selectProcOrderExecutionList(procOrderExecution);
        ExcelUtil<ProcOrderExecution> util = new ExcelUtil<ProcOrderExecution>(ProcOrderExecution.class);
        return util.exportExcel(list, "采购订单执行记录数据");
    }

    /**
     * 新增采购订单执行记录
     */
    @RequiresPermissions("purchase:execution:add")
    @GetMapping("/add")
    public String add()
    {
        return prefix + "/add";
    }

    /**
     * 新增保存采购订单执行记录
     */
    @RequiresPermissions("purchase:execution:add")
    @Log(title = "采购订单执行记录", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(ProcOrderExecution procOrderExecution)
    {
        return toAjax(procOrderExecutionService.insertProcOrderExecution(procOrderExecution));
    }

    /**
     * 修改采购订单执行记录
     */
    @RequiresPermissions("purchase:execution:edit")
    @GetMapping("/edit/{executionId}")
    public String edit(@PathVariable("executionId") Long executionId, ModelMap mmap)
    {
        ProcOrderExecution procOrderExecution = procOrderExecutionService.selectProcOrderExecutionByExecutionId(executionId);
        mmap.put("procOrderExecution", procOrderExecution);
        return prefix + "/edit";
    }

    /**
     * 修改保存采购订单执行记录
     */
    @RequiresPermissions("purchase:execution:edit")
    @Log(title = "采购订单执行记录", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(ProcOrderExecution procOrderExecution)
    {
        return toAjax(procOrderExecutionService.updateProcOrderExecution(procOrderExecution));
    }

    /**
     * 删除采购订单执行记录
     */
    @RequiresPermissions("purchase:execution:remove")
    @Log(title = "采购订单执行记录", businessType = BusinessType.DELETE)
    @PostMapping( "/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        return toAjax(procOrderExecutionService.deleteProcOrderExecutionByExecutionIds(ids));
    }
    
    /**
     * 执行采购订单
     */
    @RequiresPermissions("purchase:execution:add")
    @Log(title = "执行采购订单", businessType = BusinessType.UPDATE)
    @PostMapping("/executeOrder")
    @ResponseBody
    public AjaxResult executeOrder(Long orderId, String executionRemark, Long accountId)
    {
        if (accountId != null) {
            return toAjax(procOrderService.executeOrder(orderId, executionRemark, accountId));
        } else {
            return toAjax(procOrderService.executeOrder(orderId, executionRemark));
        }
    }
    
    /**
     * 批量执行所有审核通过的采购订单
     */
    @RequiresPermissions("purchase:execution:add")
    @Log(title = "批量执行采购订单", businessType = BusinessType.UPDATE)
    @PostMapping("/executeAllApproved")
    @ResponseBody
    public AjaxResult executeAllApproved(String executionRemark, Long accountId)
    {
        try {
            if (accountId == null) {
                return AjaxResult.error("请选择财务账户");
            }
            
            if (executionRemark == null || executionRemark.trim().isEmpty()) {
                executionRemark = "批量执行审核通过的采购订单";
            }
            
            int successCount = procOrderService.executeAllApprovedOrders(executionRemark, accountId);
            
            if (successCount > 0) {
                return AjaxResult.success("成功执行 " + successCount + " 个采购订单");
            } else {
                return AjaxResult.success("没有符合条件的订单需要执行");
            }
        } catch (Exception e) {
            logger.error("批量执行采购订单失败", e);
            return AjaxResult.error("批量执行失败: " + e.getMessage());
        }
    }
    
    /**
     * 打开执行采购订单页面
     */
    @RequiresPermissions("purchase:execution:add")
    @GetMapping("/execute/{orderId}")
    public String execute(@PathVariable("orderId") Long orderId, ModelMap mmap)
    {
        mmap.put("orderId", orderId);
        
        // 获取所有可用账户列表供选择
        FinAccount queryAccount = new FinAccount();
        queryAccount.setStatus(1L); // 只查询启用状态的账户
        List<FinAccount> accounts = finAccountService.selectFinAccountList(queryAccount);
        mmap.put("accounts", accounts);
        
        return prefix + "/execute";
    }
    
    /**
     * 打开批量执行采购订单页面
     */
    @RequiresPermissions("purchase:execution:add")
    @GetMapping("/executeAll")
    public String executeAll(ModelMap mmap)
    {
        // 获取所有可用账户列表供选择
        FinAccount queryAccount = new FinAccount();
        queryAccount.setStatus(1L); // 只查询启用状态的账户
        List<FinAccount> accounts = finAccountService.selectFinAccountList(queryAccount);
        mmap.put("accounts", accounts);
        
        return prefix + "/executeAll";
    }
    
    /**
     * 打开批量执行选中订单页面
     */
    @RequiresPermissions("purchase:execution:add")
    @GetMapping("/executeBatch")
    public String executeBatch(String orderIds, ModelMap mmap)
    {
        logger.info("接收到批量执行请求，orderIds: {}", orderIds);
        mmap.put("orderIds", orderIds);
        
        // 获取所有可用账户列表供选择
        FinAccount queryAccount = new FinAccount();
        queryAccount.setStatus(1L); // 只查询启用状态的账户
        List<FinAccount> accounts = finAccountService.selectFinAccountList(queryAccount);
        logger.info("可用账户数量: {}", accounts.size());
        mmap.put("accounts", accounts);
        
        return prefix + "/executeBatch";
    }
    
    /**
     * 批量执行选中的采购订单
     */
    @RequiresPermissions("purchase:execution:add")
    @Log(title = "批量执行选中订单", businessType = BusinessType.UPDATE)
    @PostMapping("/executeBatchOrders")
    @ResponseBody
    public AjaxResult executeBatchOrders(String orderIds, String executionRemark, Long accountId)
    {
        logger.info("执行批量订单，orderIds: {}, executionRemark: {}, accountId: {}", orderIds, executionRemark, accountId);
        try {
            if (accountId == null) {
                return AjaxResult.error("请选择财务账户");
            }
            
            if (StringUtils.isEmpty(orderIds)) {
                return AjaxResult.error("未选择要执行的订单");
            }
            
            if (executionRemark == null || executionRemark.trim().isEmpty()) {
                executionRemark = "批量执行选中的采购订单";
            }
            
            String[] orderIdArray = orderIds.split(",");
            logger.info("订单ID数组长度: {}", orderIdArray.length);
            int successCount = 0;
            StringBuilder errorMsg = new StringBuilder();
            
            for (String orderIdStr : orderIdArray) {
                try {
                    Long orderId = Long.parseLong(orderIdStr);
                    // 检查订单是否审核通过
                    ProcOrder order = procOrderService.selectProcOrderByOrderId(orderId);
                    if (order != null && "1".equals(order.getAuditStatus())) {
                        int result = procOrderService.executeOrder(orderId, executionRemark, accountId);
                        if (result > 0) {
                            successCount++;
                        } else {
                            errorMsg.append("订单[").append(order.getOrderCode()).append("]执行失败; ");
                        }
                    } else {
                        errorMsg.append("订单ID[").append(orderId).append("]未审核通过或不存在; ");
                    }
                } catch (Exception e) {
                    logger.error("执行订单异常", e);
                    errorMsg.append("订单ID[").append(orderIdStr).append("]执行异常: ").append(e.getMessage()).append("; ");
                }
            }
            
            if (successCount > 0) {
                if (errorMsg.length() > 0) {
                    return AjaxResult.success("成功执行 " + successCount + " 个订单，部分订单执行失败: " + errorMsg.toString());
                } else {
                    return AjaxResult.success("成功执行 " + successCount + " 个订单");
                }
            } else {
                return AjaxResult.error("所有订单执行失败: " + errorMsg.toString());
            }
        } catch (Exception e) {
            logger.error("批量执行订单失败", e);
            return AjaxResult.error("批量执行失败: " + e.getMessage());
        }
    }
}
